package czStvDpds.mapeditor;

import czStvDpds.mapmanagment.Map;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 * Displej, na kterém se zobrazuje mapa v editoru
 *
 * @author Jiří Švejda
 */
public class MapDisplay {

    private Map map;
    private Paintbrush paintbrush;
    private int regionWidth, regionHeight, regionOffsetX, regionOffsetY, scrollingSpeed;
    private JPanel panel;
    private JLabel[][] tiles;

    public Map getMap() {
        return map;
    }

    public void setMap(Map map) {
        this.map = map;
    }

    public JPanel getPanel() {
        return panel;
    }

    public void setPanel(JPanel panel) {
        this.panel = panel;
    }

    public int getRegionHeight() {
        return regionHeight;
    }

    public void setRegionHeight(int regionHeight) {
        this.regionHeight = regionHeight;
    }

    public int getRegionOffsetX() {
        return regionOffsetX;
    }

    public void setRegionOffsetX(int regionOffsetX) {
        this.regionOffsetX = regionOffsetX;
    }

    public int getRegionOffsetY() {
        return regionOffsetY;
    }

    public void setRegionOffsetY(int regionOffsetY) {
        this.regionOffsetY = regionOffsetY;
    }

    public int getRegionWidth() {
        return regionWidth;
    }

    public void setRegionWidth(int regionWidth) {
        this.regionWidth = regionWidth;
    }

    public Paintbrush getPaintbrush() {
        return paintbrush;
    }

    public void setPaintbrush(Paintbrush paintbrush) {
        this.paintbrush = paintbrush;
    }

    public int getScrollingSpeed() {
        return scrollingSpeed;
    }

    public void setScrollingSpeed(int scrollingSpeed) {
        this.scrollingSpeed = scrollingSpeed;
    }

    public MapDisplay(Map map, Paintbrush paintbrush, int regionWidth, int regionHeight, int regionOffsetX, int regionOffsetY, int scrollingSpeed) {
        this.map = map;
        this.paintbrush = paintbrush;
        this.regionWidth = regionWidth;
        this.regionHeight = regionHeight;
        this.regionOffsetX = regionOffsetX;
        this.regionOffsetY = regionOffsetY;
        this.scrollingSpeed = scrollingSpeed;
    }

    public void init() {
        panel = new JPanel(new GridLayout(regionHeight, regionWidth));
        panel.addMouseListener(new PanelML());
        panel.addMouseMotionListener(new PanelML());
        initTiles();
        addTiles();
    }

    public void initTiles() {
        tiles = new JLabel[regionWidth][regionHeight];
        int labelX = 0;
        int labelY = 0;
        for (int x = regionOffsetX; x < regionOffsetX + regionWidth; x++) {
            for (int y = regionOffsetY; y < regionOffsetY + regionHeight; y++) {
                tiles[labelX][labelY] = new JLabel("", JLabel.CENTER);
                tiles[labelX][labelY].setBackground(TileTypeManager.getColor(map.getTile(x, y).getId()));
                tiles[labelX][labelY].setOpaque(true);

                labelY++;
            }
            labelX++;
            labelY = 0;
        }
    }

    public void addTiles() {
        for (int x = 0; x < regionWidth; x++) {
            for (int y = 0; y < regionHeight; y++) {
                panel.add(tiles[y][x]);
            }
        }
    }

    /**
     * Aktualizuje dlaždice, volá se při změně offsetX/offsetY
     */
    public void updateTiles() {
        panel.setVisible(false);

        int labelX = 0;
        int labelY = 0;
        for (int x = regionOffsetX; x < regionOffsetX + regionWidth; x++) {
            for (int y = regionOffsetY; y < regionOffsetY + regionHeight; y++) {
                tiles[labelX][labelY].setBackground(TileTypeManager.getColor(map.getTile(x, y).getId()));
                tiles[labelX][labelY].setOpaque(true);

                labelY++;
            }
            labelX++;
            labelY = 0;
        }

        panel.setVisible(true);
    }
    Point lastKnownMousePositon = new Point();

    /**
     * Vykreslí myš na zadané pozici v dlaždicích
     */
    public void paintMouse(int realX, int realY) {
        int x = realX / (panel.getWidth() / regionWidth);
        int y = realY / (panel.getHeight() / regionHeight);
        for (int drawX = x - paintbrush.getSize(); drawX <= x + paintbrush.getSize(); drawX++) {
            for (int drawY = y - paintbrush.getSize(); drawY <= y + paintbrush.getSize(); drawY++) {
                if (drawX >= 0 && drawX < regionWidth && drawY >= 0 && drawY < regionHeight) {
                    tiles[drawX][drawY].setBackground(TileTypeManager.getColor(paintbrush.getPaintedTile().getId()));
                    tiles[drawX][drawY].setOpaque(true);
                }
            }
        }
    }

    /**
     * Vynutí vykreslení myši
     */
    public void repaintMouse() {
        updateTiles();
        paintMouse((int) Math.round(lastKnownMousePositon.getX()), (int) Math.round(lastKnownMousePositon.getY()));
    }

    class PanelML extends MouseAdapter {

        @Override
        public void mousePressed(MouseEvent e) {
            actionDetected(e);
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            if (e.getX() > 0 && e.getX() < panel.getWidth() && e.getY() > 0 && e.getY() < panel.getHeight()) {
                actionDetected(e);
                lastKnownMousePositon.x = e.getX();
                lastKnownMousePositon.y = e.getY();
            }
        }

        @Override
        public void mouseMoved(MouseEvent e) {
            updateTiles();
            paintMouse(e.getX(), e.getY());
            lastKnownMousePositon.x = e.getX();
            lastKnownMousePositon.y = e.getY();
        }

        public void actionDetected(MouseEvent e) {
            int x = e.getX() / (panel.getWidth() / regionWidth);
            int y = e.getY() / (panel.getHeight() / regionHeight);

            int mapX = x + regionOffsetX;
            int mapY = y + regionOffsetY;

            // Vykreslit
            for (int drawX = mapX - paintbrush.getSize(); drawX <= mapX + paintbrush.getSize(); drawX++) {
                for (int drawY = mapY - paintbrush.getSize(); drawY <= mapY + paintbrush.getSize(); drawY++) {
                    if (map.getTile(drawX, drawY) != null) {
                        map.setTile(drawX, drawY, paintbrush.getPaintedTile());
                    }
                }
            }

            updateTiles();
        }
    }
}
